/*
 * @Author: lirl
 * @Date: 2022-07-18 10:15:53
 * @Description: 路由文件
 */
import Vue from 'vue';
import Router from 'vue-router';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import { SystemLoginService } from 'jdf-jssdk';
import { pick } from 'lodash-es';
import { MessageBox } from 'element-ui';
import { window } from 'globalthis/implementation';
import {
  bizServiceURL,
  routerBase,
  routerMode,
  ssoLoginPageURL,
} from '@/api/utils/constants';
import store from '@/vuex/store';
import { isDevEnv } from '@/utils/utils';
import settings from '@/settings/settings';
import { constructRoutes as buildRoutes } from './permission/menu';
import staticRouters from './staticRouters';

Vue.use(Router);

const router = new Router({
  mode: routerMode,
  base: routerBase,
  scrollBehavior(to, from, savedPosition) {
    return savedPosition || { x: 0, y: 0 };
  },
  routes: [
    ...staticRouters
  ]
});
/**
 * 动态添加路由的方法 - 解决直接使用router.addRoutes会提示Duplicate named routes definition的问题。
 * 原因：addRoutes 方法仅仅是注入新的路由，并没有剔除其它路由！
 * 解决方法：通过新建一个全新的 Router，然后将新的 Router.matcher 赋给当前页面的管理 Router，以达到更新路由配置的目的
 */
router.$addRoutes = (params) => {
  router.matcher = new Router({ mode: 'history' }).matcher;
  router.addRoutes(params);
};

NProgress.configure({ showSpinner: false });

router.beforeEach((to, from, next) => {
  sessionStorage.setItem(settings.sdkAuthKey, JSON.stringify(settings.authObj));
  const { path } = to;
  if (settings.whiteList.includes(path)) {
    next();
    return;
  }
  NProgress.start();

  // 路由相关参数
  const routerInfo = {
    to,
    next,
    staticRouters,
    store,
    router,
    constructRoutes: () => buildRoutes(router, store, to),
  };
  // 项目设置
  const bizSettings = {
    ...pick(settings, ['bffTokenKey', 'bizTokenKey', 'accessTokenKey', 'authObj']),
    cookieTokenKey: 'flow_it_token',
    ssoLoginPageURL
  };
  // 系统登录工具实例
  const systemLogin = new SystemLoginService(bizServiceURL, routerInfo, bizSettings, isDevEnv());

  // 执行登录
  systemLogin.routerBeforeEach(`/${process.env.VUE_APP_LOGIN_URL}`, (userInfo) => {
    // 单点登录成功回调
    // 将登录数据放到vuex中
    store.commit('user/setUser', userInfo);
  }, () => {
    // 单点登录失败回调
    NProgress.done();
    MessageBox.alert('单点登录失败', '提示', {
      type: 'warning',
      callback: () => {
        window.open(ssoLoginPageURL, '_self');
      }
    });
  });
});

router.afterEach(() => {
  NProgress.done();
});

export default router;
